package org.optaplanner.examples.apsplanning.domain;

import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningScore;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.bendable.BendableScore;
import org.optaplanner.examples.common.domain.AbstractPersistable;
import org.optaplanner.examples.taskassigning.domain.Task;

import java.util.List;

/**
 * @author andaolong
 * @time 2021/3/27-10:51
 * @describe 仿照taskassigning中的TaskAssigningSolution
 */
@PlanningSolution
public class ApsPlanningSolution extends AbstractPersistable {

    //这几个都是问题事实，也就是，初始数据
    //排程数据初始化的时候，会载入这些数据
    //@ProblemFactCollectionProperty
    //private List<MachiningType> machiningTypeList;
    //@ProblemFactCollectionProperty
    //private List<Process> processList;
    @ValueRangeProvider(id = "deviceRange")
    @ProblemFactCollectionProperty
    private List<Device> deviceList;

    //指定PlanningSolution类上的属性（或字段）是计划实体的集合。
    //计划实体集合中的每个元素都应具有PlanningEntity批注。计划实体集合中的每个元素都将添加到ScoreDirector。
    @PlanningEntityCollectionProperty
    @ValueRangeProvider(id = "bomTaskRange")
    private List<BomTask> bomTaskList;

    //这个也加上，drools函数好像用得上，但是另外两个问题事实，初始化的时候就传进来了，这个process其实是附在bomTask上的。。
    @ProblemFactCollectionProperty
    private List<Process> processList;

    //PlaningScore表示该property保存着该solution的得分
    //分数这里，硬分数和软分数也可以定义多个级别，其中，硬分数级别0总是重于硬分数级别1，其他类推
    //多个分数级别的话，更能满足实际情境的需求
    @PlanningScore(bendableHardLevelsSize = 2, bendableSoftLevelsSize = 2)
    private BendableScore score;

    /**
     * Relates to {@link Task#getStartTime()}.
     */
    //这个是什么还不知道
    private int frozenCutoff; // In minutes

    public ApsPlanningSolution() {
    }

    //有参构造参数,用来给solution初始化
    //感觉这些参数之外的那些参数这样传进去也没有用，比如machiningTypeList附在deviceList身上传进去了
    public ApsPlanningSolution(long id, List<Device> deviceList, List<BomTask> bomTaskList) {
        super(id);
        this.deviceList = deviceList;
        this.bomTaskList = bomTaskList;
    }

    //有参构造参数02,用来给solution初始化
    //感觉这些参数之外的那些参数这样传进去也没有用，比如machiningTypeList附在deviceList身上传进去了
    public ApsPlanningSolution(long id, List<Device> deviceList, List<BomTask> bomTaskList,List<Process> processList) {
        super(id);
        this.deviceList = deviceList;
        this.bomTaskList = bomTaskList;
        this.processList = processList;
    }

    //public List<MachiningType> getMachiningTypeList() {
    //    return machiningTypeList;
    //}
    //
    //public void setMachiningTypeList(List<MachiningType> machiningTypeList) {
    //    this.machiningTypeList = machiningTypeList;
    //}

    //public List<Process> getProcessList() {
    //    return processList;
    //}
    //
    //public void setProcessList(List<Process> processList) {
    //    this.processList = processList;
    //}
    //

    public List<Device> getDeviceList() {
        return deviceList;
    }

    public void setDeviceList(List<Device> deviceList) {
        this.deviceList = deviceList;
    }

    public List<BomTask> getBomTaskList() {
        return bomTaskList;
    }

    public void setBomTaskList(List<BomTask> bomTaskList) {
        this.bomTaskList = bomTaskList;
    }

    public BendableScore getScore() {
        return score;
    }

    public void setScore(BendableScore score) {
        this.score = score;
    }

    public int getFrozenCutoff() {
        return frozenCutoff;
    }

    public void setFrozenCutoff(int frozenCutoff) {
        this.frozenCutoff = frozenCutoff;
    }

    // ************************************************************************
    // Complex methods
    // ************************************************************************

}
